# -*- coding: utf-8 -*-
# standard
import os
import sys

# third

# local
_P_PATH =  os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
if _P_PATH not in sys.path:
    sys.path.append(_P_PATH)
from models import *


"""
@Title:   
@File: setting_func.py
@Author: walle 2024年12日31日 10时49分07秒
@Version: 1.0.0
@Desc: 
"""


def dump_notification_strategy(notification_strategy: NotificationStrategyOrm) -> Tuple[dict, List[str]]:
    """
    把推送策略的实例转化为字典
    :param notification_strategy: _description_
    :return: _description_
    """
    temp = notification_strategy.to_dict(to_plain=True)
    temp['cond'] = notification_strategy.cond.to_dict(to_plain=True)
    methods = []
    target_infos = []
    for method in notification_strategy.methods:
        target_infos.extend(method.get_targets())
        methods.append(method.to_dict(to_plain=True))
    temp['methods'] = methods
    temp['priorities'] = notification_strategy.priorities
    temp['mute_times'] = [x.to_dict(to_plain=True) for x in notification_strategy.mute_times]
    return temp, target_infos


def page_notification_strategies_old(keyword: str | None = None,
                                 customer_id: int | None = None,
                                 store_id: int | None = None,
                                 method_name: str | None = None,
                                 source_name: str | None = None,
                                 page_num: int = 1, id: int | None = None,
                                 page_size: int = 10) -> Resp:
    """
    分页获取推送策略
    """
    db_session, resp = new_db_session(sync=True), Resp()
    s = select(
        NotificationStrategyOrm
    ).options(
        joinedload(NotificationStrategyOrm.cond),
        joinedload(NotificationStrategyOrm.methods),
    ).where(NotificationStrategyOrm.is_deleted == 0)
    if id:
        s = s.where(NotificationStrategyOrm.id == id)
    if keyword:
        s = s.where(NotificationStrategyOrm.name.like(f'%{keyword}%'))
    if customer_id:
        s = s.where(NotificationStrategyOrm.customer_id == customer_id)
    if store_id:
        s = s.where(NotificationStrategyOrm.cond.has(NotificationConditionOrm.store_ids.any(store_id, operator=operators.eq)))
    if method_name:
        s = s.where(NotificationStrategyOrm.methods.any(NotificationMethodOrm.name == method_name))
    if source_name:
        s = s.where(NotificationStrategyOrm.cond.has(NotificationConditionOrm.sources.any(source_name, operator=operators.eq)))  
    total = db_session.scalar(select(func.count()).select_from(s))
    s = s.order_by(NotificationStrategyOrm.update_time.desc()).offset((page_num - 1) * page_size).limit(page_size)
    data = []
    for notification_strategy in db_session.scalars(s).unique():
        temp = dump_notification_strategy(notification_strategy)
        data.append(temp)
    db_session.close()
    resp.data = paging_data(data=data, total=total, page_num=page_num, page_size=page_size)
    return resp


def page_notification_strategies(keyword: str | None = None,
                                 customer_id: int | None = None,
                                 store_id: int | None = None,
                                 method_name: str | None = None,
                                 source_name: str | None = None,
                                 page_num: int = 1, id: int | None = None,
                                 page_size: int = 10) -> Resp:
    """
    分页获取推送策略
    """
    db_session, resp = new_db_session(sync=True), Resp()
    s = select(
        NotificationStrategyOrm
    ).options(
        joinedload(NotificationStrategyOrm.cond),
        joinedload(NotificationStrategyOrm.methods),
    ).where(NotificationStrategyOrm.is_deleted == 0)
    if id:
        s = s.where(NotificationStrategyOrm.id == id)
    if keyword:
        s = s.where(NotificationStrategyOrm.name.like(f'%{keyword}%'))
    if customer_id:
        s = s.where(NotificationStrategyOrm.customer_id == customer_id)
    if store_id:
        s = s.where(NotificationStrategyOrm.cond.has(NotificationConditionOrm.store_ids.any(store_id, operator=operators.eq)))
    if method_name:
        s = s.where(NotificationStrategyOrm.methods.any(NotificationMethodOrm.name == method_name))
    if source_name:
        s = s.where(NotificationStrategyOrm.cond.has(NotificationConditionOrm.sources.any(source_name, operator=operators.eq)))  
    total = db_session.scalar(select(func.count()).select_from(s))
    s = s.order_by(NotificationStrategyOrm.update_time.desc()).offset((page_num - 1) * page_size).limit(page_size)
    data = []
    targets = []
    for notification_strategy in db_session.scalars(s).unique():
        temp, cur_targets = dump_notification_strategy(notification_strategy)
        data.append(temp)
        targets.extend(cur_targets)
    # 查询别名
    s = select(
        NotificationTargetCommentOrm.customer_id,
        NotificationTargetCommentOrm.method_name,
        NotificationTargetCommentOrm.key,
        NotificationTargetCommentOrm.desc,
    ).where(
        NotificationTargetCommentOrm.key.in_(targets)
    )
    key_desc = [{
        "customer_id": x.customer_id,
        "method_name": x.method_name,
        "key": x.key,
        "desc": x.desc,
    } for x in db_session.execute(s)]  
    db_session.close()
    # 补足key别名信息
    for x in data:
        cur_customer_id = x['customer_id']
        for m in x['methods']:
            cur_method_name = m['name']
            if cur_method_name == NotificationMethodName.SMS.value or cur_method_name == NotificationMethodName.TEL.value:
                column = 'phones'
            elif cur_method_name == NotificationMethodName.WX_MES.value:
                column = "open_ids"
            else:
                column = 'group_keys'
            new_targets = []
            for cur_key in m[column]:
                for item in key_desc:
                    if cur_customer_id == item['customer_id'] and cur_method_name == item['method_name'] and cur_key == item['key']:
                        new_targets.append({
                            "key": cur_key, "desc": item['desc']
                        })
                        break
            m[column] = new_targets
    resp.data = paging_data(data=data, total=total, page_num=page_num, page_size=page_size)
    return resp


async def page_notification_strategies_async(id: int | None = None,
                                             keyword: str | None = None,
                                             customer_ids: List[int] | None = None,
                                             store_ids: List[int] | None = None,
                                             method_name: NotificationMethodName | None = None,
                                             notification_target: str | None = None,
                                             source_name: NotificationSource | None = None,
                                             page_num: int = 1,
                                             page_size: int = 10) -> Resp:
    """
    分页获取推送策略
    """
    db_session, resp = new_db_session(sync=True), Resp()
    s = select(
        NotificationStrategyOrm
    ).options(
        selectinload(NotificationStrategyOrm.cond),
        selectinload(NotificationStrategyOrm.methods),
        selectinload(NotificationStrategyOrm.mute_times),
    ).where(NotificationStrategyOrm.is_deleted == 0)
    if id:
        s = s.where(NotificationStrategyOrm.id == id)
    if keyword:
        s = s.where(NotificationStrategyOrm.name.like(f'%{keyword}%'))
    if customer_ids:
        s = s.where(NotificationStrategyOrm.customer_id.in_(customer_ids))
    if store_ids:
        # s = s.where(NotificationStrategyOrm.cond.has(NotificationConditionOrm.store_ids.any(store_id, operator=operators.eq)))
        s = s.where(NotificationStrategyOrm.cond.has(NotificationConditionOrm.store_ids.op('&&')(store_ids)))
    if method_name:
        s = s.where(NotificationStrategyOrm.methods.any(NotificationMethodOrm.name == method_name.value))
    if source_name:
        s = s.where(NotificationStrategyOrm.cond.has(NotificationConditionOrm.sources.any(source_name.value, operator=operators.eq)))  
    if notification_target:
        s1 = select(
            NotificationTelOrm.strategy_id
        ).where(NotificationTelOrm.phones.any(notification_target, operator=operators.eq))
        s2 = select(
            NotificationShortMessageOrm.strategy_id
        ).where(NotificationShortMessageOrm.phones.any(notification_target, operator=operators.eq))
        s3 = select(
            NotificationWXMessageOrm.strategy_id
        ).where(NotificationWXMessageOrm.open_ids.any(notification_target, operator=operators.eq))
        s4 = select(
            NotificationFeiShuGroupOrm.strategy_id
        ).where(NotificationFeiShuGroupOrm.group_keys.any(notification_target, operator=operators.eq))
        s5 = select(
            NotificationWWXGroupOrm.strategy_id
        ).where(NotificationWWXGroupOrm.group_keys.any(notification_target, operator=operators.eq))
        s6 = select(
            NotificationDDGroupOrm.strategy_id
        ).where(NotificationDDGroupOrm.group_keys.any(notification_target, operator=operators.eq))
        if method_name:
            if method_name == NotificationMethodName.FEISHU: # 飞书
                s = s.where(NotificationStrategyOrm.id.in_(s4.subquery()))
            elif method_name == NotificationMethodName.DD_GROUP:  # 钉钉群
                s = s.where(NotificationStrategyOrm.id.in_(s6.subquery()))
            elif method_name == NotificationMethodName.WX_MES:  # 微信消息
                s = s.where(NotificationStrategyOrm.id.in_(s3.subquery()))
            elif method_name == NotificationMethodName.WORK_WX_GROUP: # 企业微信群
                s = s.where(NotificationStrategyOrm.id.in_(s5.subquery()))
            elif method_name == NotificationMethodName.SMS: # 短信
                s = s.where(NotificationStrategyOrm.id.in_(s2.subquery()))
            else: # 电话
                s = s.where(NotificationStrategyOrm.id.in_(s1.subquery()))
        else:
            sub_all = s1.union_all(s2, s3, s4, s5, s6).subquery()
            s = s.where(NotificationStrategyOrm.id.in_(sub_all))

    total = db_session.scalar(select(func.count()).select_from(s))
    s = s.order_by(NotificationStrategyOrm.update_time.desc()).offset((page_num - 1) * page_size).limit(page_size)
    data = []
    targets = []
    for notification_strategy in db_session.scalars(s).unique():
        temp, cur_targets = dump_notification_strategy(notification_strategy)
        data.append(temp)
        targets.extend(cur_targets)
    # 查询别名
    s = select(
        NotificationTargetCommentOrm.customer_id,
        NotificationTargetCommentOrm.method_name,
        NotificationTargetCommentOrm.key,
        NotificationTargetCommentOrm.desc,
    ).where(
        NotificationTargetCommentOrm.key.in_(targets)
    )
    key_desc = [{
        "customer_id": x.customer_id,
        "method_name": x.method_name,
        "key": x.key,
        "desc": x.desc,
    } for x in db_session.execute(s)]  
    db_session.close()
    # 补足key别名信息
    for x in data:
        cur_customer_id = x['customer_id']
        for m in x['methods']:
            cur_method_name = m['name']
            if cur_method_name == NotificationMethodName.SMS.value or cur_method_name == NotificationMethodName.TEL.value:
                column = 'phones'
            elif cur_method_name == NotificationMethodName.WX_MES.value:
                column = "open_ids"
            else:
                column = 'group_keys'
            new_targets = []
            for cur_key in m[column]:
                for item in key_desc:
                    if cur_customer_id == item['customer_id'] and cur_method_name == item['method_name'] and cur_key == item['key']:
                        new_targets.append({
                            "key": cur_key, "desc": item['desc']
                        })
                        break
            m[column] = new_targets
    resp.data = paging_data(data=data, total=total, page_num=page_num, page_size=page_size)
    return resp


if __name__ == '__main__':
    pass